package com.ybl.store.backend.service.impl.store;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ybl.store.backend.dao.entity.store.LogProductNumberDO;
import com.ybl.store.backend.dao.mapper.store.LogProductNumberMapper;
import com.ybl.store.backend.dto.UserInfoDTO;
import com.ybl.store.backend.dto.req.store.LogProductNumberSaveReqDTO;
import com.ybl.store.backend.dto.req.store.LogProductNumberUpdateReqDTO;
import com.ybl.store.backend.dto.resp.store.LogProductNumberPageRespDTO;
import com.ybl.store.backend.service.store.LogProductNumberService;
import com.ybl.store.backend.service.store.ProductService;
import com.ybl.store.common.constant.InOutType;
import com.ybl.store.common.constant.UserPermission;
import com.ybl.store.common.context.UserContext;
import com.ybl.store.common.convention.errorcode.BaseErrorCode;
import com.ybl.store.common.convention.exception.ClientException;
import com.ybl.store.common.entity.ListRespDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
@Transactional
public class LogProductNumberServiceImpl extends ServiceImpl<LogProductNumberMapper, LogProductNumberDO> implements LogProductNumberService {

    private final ProductService productService;

    @Override
    public void saveLogProductNumber(LogProductNumberSaveReqDTO requestParam) {
        if (requestParam.getType() == InOutType.in) {
            productService.addNumber(requestParam.getProductId(), requestParam.getNumber());
        }
        else {
            productService.subNumber(requestParam.getProductId(), requestParam.getNumber());
        }

        int result = baseMapper.insert(BeanUtil.toBean(requestParam, LogProductNumberDO.class));
        if (result < 1) {
            throw new ClientException(BaseErrorCode.LOG_SAVE_ERROR);
        }
    }

    @Override
    public void deleteLogProductNumberById(Long id) {
        LogProductNumberDO logProductNumberDO = baseMapper.selectById(id);
        if (logProductNumberDO == null) {
            throw new ClientException(BaseErrorCode.LOG_DELETE_ERROR);
        }
        if (logProductNumberDO.getType() == InOutType.in) {
            productService.subNumber(logProductNumberDO.getProductId(), logProductNumberDO.getNumber());
        }
        else {
            productService.addNumber(logProductNumberDO.getProductId(), logProductNumberDO.getNumber());
        }

        int result = baseMapper.deleteById(id);
        if (result < 1) {
            throw new ClientException(BaseErrorCode.LOG_DELETE_ERROR);
        }
    }

    @Override
    public void updateLogProductNumber(LogProductNumberUpdateReqDTO requestParam) {
        LogProductNumberDO logProductNumberDO = baseMapper.selectById(requestParam.getId());
        if (logProductNumberDO == null) {
            throw new ClientException(BaseErrorCode.LOG_NULL_ERROR);
        }

        if (requestParam.getType() == InOutType.in) {
            productService.addNumber(requestParam.getProductId(), requestParam.getNumber());
        }
        else {
            productService.subNumber(requestParam.getProductId(), requestParam.getNumber());
        }
        if (logProductNumberDO.getType() == InOutType.in) {
            productService.subNumber(logProductNumberDO.getProductId(), logProductNumberDO.getNumber());
        }
        else {
            productService.addNumber(logProductNumberDO.getProductId(), logProductNumberDO.getNumber());
        }

        int result = baseMapper.updateById(BeanUtil.toBean(requestParam, LogProductNumberDO.class));
        if (result < 1) {
            throw new ClientException(BaseErrorCode.LOG_UPDATE_ERROR);
        }
    }

    @Override
    public ListRespDTO<LogProductNumberPageRespDTO> pageLogProductNumber(Integer pn, Integer ps, Long productId) {
        Long storeId = null;
        UserInfoDTO userInfoDTO = UserContext.get();
        if (!Objects.equals(userInfoDTO.getPermission(), UserPermission.ADMIN)) {
            storeId = userInfoDTO.getStoreId();
        }

        Page<LogProductNumberPageRespDTO> page = new Page<>(pn, ps);
        QueryWrapper<LogProductNumberDO> queryWrapper = Wrappers.query(LogProductNumberDO.class)
                .eq(Objects.nonNull(productId), "t_product.id", productId)
                .eq(Objects.nonNull(storeId), "t_product.store_id", storeId)
                .eq("log.del_flag", 0)
                .orderByDesc("log.log_time");
        List<LogProductNumberPageRespDTO> logProductPageRespDTOList = baseMapper.pageLogProduct(page, queryWrapper);

        queryWrapper = Wrappers.query(LogProductNumberDO.class)
                .eq(Objects.nonNull(productId), "t_product.id", productId)
                .eq(Objects.nonNull(storeId), "t_product.store_id", storeId)
                .eq("log.del_flag", 0);
        Long total = baseMapper.count(queryWrapper);

        return ListRespDTO.<LogProductNumberPageRespDTO>builder()
                .total(total)
                .items(logProductPageRespDTOList)
                .build();
    }
}
